"use strict";
const Service = require("egg").Service;
const { httpCode } = require("../../utils/userConfig")
const crypto = require('crypto');
const AuthException = require('../../exception/authException');
const SystemErrException = require("../../exception/systemError");
const Qiniu = require("../../utils/qiniu");
const { Op, Sequelize } = require("sequelize");
const moment = require('moment')
class MonitorPartnersService extends Service {

  async add(monitorPartners) {
    try {
      const { ctx } = this;
      let { enterCameraIp, outCameraIp } = monitorPartners;
      if (enterCameraIp == outCameraIp) {
        return {
          code: httpCode.LOGICERROR,
          message: "入口IP不能和出口IP相同",
        };
      }
      let rows = await ctx.model.Videos.MonitorPartners.findAll({
        where: {
          [Op.or]: [{ enterCameraIp }, { outCameraIp }]
        },
        raw: true
      });
      if (rows.length != 0) {
        return {
          code: httpCode.LOGICERROR,
          message: "入口或出口IP已存在其他设备组，请检查",
        };
      }

      await ctx.model.Videos.MonitorPartners.create(monitorPartners);
      return {
        code: httpCode.SUCCESS,
        message: "设备组添加成功",
      };
    } catch (error) {
      throw new SystemErrException("新增设备组异常：" + error);
    }
  }

  async list(requestData) {
    try {
      const { ctx, app } = this;
      const {
        partnerName,
        pageSize = 300,
        currentPage = 1,
        ip,
        status
      } = requestData;

      let searchCondition = {
        [Op.or]: [{
          outCameraIp: {
            [Op.substring]: ip,
          }
        },
        {
          enterCameraIp: {
            [Op.substring]: ip,
          }
        }]
      };
      if (partnerName) {
        searchCondition.partnerName = {
          [Op.substring]: partnerName,
        }
      }
      if (status) {
        searchCondition.status = status;
      }
      let { count, rows } = await ctx.model.Videos.MonitorPartners.findAndCountAll({
        where: searchCondition,
        raw: true,
        offset: (currentPage - 1) * pageSize,
        limit: Number(pageSize),
        order: [['create_date', 'desc']]
      });

      rows.forEach(item => {
        let { enterCameraRemark, outCameraRemark, partnerRemark } = item;
        item.enterCameraRemark = enterCameraRemark || '--'
        item.outCameraRemark = outCameraRemark || '--'
        item.partnerRemark = partnerRemark || '--'
      })

      return {
        data: {
          data: rows,
          count,
        },
        code: httpCode.SUCCESS,
        message: '设备组查询成功！'
      }
    } catch (error) {
      this.ctx.logger.error(requestData);
      throw new SystemErrException("设备组查询异常：" + error);
    }
  }

  async update(monitorPartners) {
    try {
      const { ctx } = this;
      let { id } = monitorPartners;
      delete monitorPartners.id;
      monitorPartners.updateDate = new Date();
      await ctx.model.Videos.MonitorPartners.update(monitorPartners, {
        where: {
          id
        }
      });
      return {
        code: httpCode.SUCCESS,
        message: "设备组更新成功",
      };
    } catch (error) {
      throw new SystemErrException("设备组更新异常：" + error);
    }
  }

  async status(requestData) {
    try {
      const { ctx } = this;
      let { id, status } = requestData;
      let updateData = {
        status,
        updateDate: new Date()
      }
      if ([5, 6].includes(status)) {
        updateData.monitorNumsUnusualDate = null;
        updateData.monitorSecondsDate = null;
      }
      if (status == 1) {
        // 获取入口最新一条数据
        let partner = await ctx.model.Videos.MonitorPartners.findOne({
          where: {
            id
          },
          raw: true
        });
        let enterNewest = await ctx.model.Videos.Logs.findOne({
          where: {
            unitip: partner.enterCameraIp
          },
          attributes: ['count', 'unitip', 'datetime'],
          raw: true,
          order: [['datetime', 'desc']]
        });
        let outNewest = await ctx.model.Videos.Logs.findOne({
          where: {
            unitip: partner.outCameraIp
          },
          attributes: ['count', 'unitip', 'datetime'],
          raw: true,
          order: [['datetime', 'desc']]
        });
        updateData.initEnterNum = enterNewest.count;
        updateData.initOutNum = outNewest.count;
      }
      await ctx.model.Videos.MonitorPartners.update(updateData, {
        where: {
          id
        }
      });
      return {
        code: httpCode.SUCCESS,
        message: "设备组状态更新成功",
      };
    } catch (error) {
      throw new SystemErrException("设备组状态更新异常：" + error);
    }
  }

  async delete(id) {
    let transaction;
    try {
      const { ctx } = this;
      transaction = await ctx.model.transaction();
      await ctx.model.Videos.MonitorPartners.destroy({
        where: { id }
      })
      return {
        code: httpCode.SUCCESS,
        message: '设备组删除成功！'
      }
    } catch (error) {
      await transaction.rollback();
      throw new SystemErrException("设备组删除异常：" + error);
    }
  }

  async hasUnusual() {
    try {
      const { ctx, app } = this;
      let rows = await ctx.model.Videos.MonitorPartners.findAll({
        where: {
          status: 4
        },
        raw: true,
        order: [['create_date', 'desc']]
      });

      return {
        data: rows,
        code: httpCode.SUCCESS,
        message: '异常设备组查询成功！'
      }
    } catch (error) {
      this.ctx.logger.error(requestData);
      throw new SystemErrException("异常设备组查询异常：" + error);
    }
  }


  async dayData(requestData) {
    try {
      const { ctx, app } = this;
      let monitorPartner = await ctx.model.Videos.MonitorPartners.findOne({
        where: {
          id: requestData.id
        },
        raw: true
      });
      let { enterCameraIp, outCameraIp } = monitorPartner
      let rows = await ctx.model.Videos.Logs.findAll({
        where: {
          [Sequelize.Op.and]: [{
            unitip: {
              [Op.in]: [enterCameraIp, outCameraIp]
            }
          }, Sequelize.where(Sequelize.fn('DATE', Sequelize.col('datetime')),
            Sequelize.literal('CURRENT_DATE'))]
        },
        raw: true
      });

      // 分组
      let uniObj = {}
      rows.forEach(row => {
        if (uniObj.hasOwnProperty(row.unitip)) {
          uniObj[row.unitip].push(row);
        } else {
          uniObj[row.unitip] = [row]
        }
      })

      // 时间段
      let timeSteps = [];
      for (const key in uniObj) {
        let datas = uniObj[key];
        const hourlyData = Array(24).fill(0);
        datas.forEach(data => {
          let { datetime, count } = data;
          let hour = moment(datetime).format('H');
          let curCount = hourlyData[Number(hour)];
          if (count > curCount) {
            hourlyData[Number(hour)] = count;
          }
          console.log(123);
        })
        timeSteps.push({
          name: enterCameraIp == key ? '入口' : '出口',
          data: hourlyData,
          type: "line",
        })
      }
      return {
        data: timeSteps,
        code: httpCode.SUCCESS,
        message: '日线图查询成功！'
      }
    } catch (error) {
      this.ctx.logger.error(requestData);
      throw new SystemErrException("日线图查询异常：" + error);
    }
  }

  async datasPan() {
    try {
      const { ctx, app } = this;
      let partners = await ctx.model.Videos.MonitorPartners.findAll({
        raw: true,
        order: [['create_date', 'desc']]
      });

      // 获取异常设备组单的ip
      let ips = [];
      partners.forEach(partner => {
        let { enterCameraIp, outCameraIp, partnerName, id: partnerId, initNum } = partner;
        initNum = Number(initNum);
        ips.push({
          ip: enterCameraIp,
          enterCameraIp,
          partnerName,
          partnerId,
          initNum
        }, {
          ip: outCameraIp,
          outCameraIp,
          partnerName,
          partnerId,
          initNum
        });

      });
      // 获取ip的最新一条信息
      let ipLogsPromises = ips.map(async ip => {
        let newest = await ctx.model.Videos.Logs.findOne({
          where: {
            unitip: ip.ip
          },
          attributes: ['count', 'unitip', 'datetime'],
          raw: true,
          order: [['datetime', 'desc']]
        });
        if (newest) {
          newest.partnerName = ip.partnerName;
          newest.value = newest.count;
          newest.partnerId = ip.partnerId;
          return newest;
        }
      })

      let newsestLogs = (await Promise.all(ipLogsPromises)).filter(Boolean);

      partners.forEach(partner => {
        let { enterCameraIp, outCameraIp, maxPercent, monitorNums, initNum, initEnterNum, initOutNum } = partner;
        newsestLogs.forEach(log => {
          let { count, unitip } = log;
          if (enterCameraIp == unitip) {
            partner.enterCameraIpNum = count
          }
          if (outCameraIp == unitip) {
            partner.outCameraIpNum = count
          }
        })
        if (partner.enterCameraIpNum && partner.outCameraIpNum) {
          partner.enterCameraIpNum = partner.enterCameraIpNum - initEnterNum;
          partner.outCameraIpNum = partner.outCameraIpNum - initOutNum;

          partner.diffNum = partner.enterCameraIpNum - partner.outCameraIpNum;
          partner.dangerNum = Math.floor(monitorNums * maxPercent);
          partner.dangerPercent = ((partner.diffNum / partner.dangerNum) * 100).toFixed(1) + '%'
        }
      })

      let allPartnersNums = partners.length; // 设备组总数
      let unusualNums = (partners.filter(item => item.status == 4)).length; // 异常道路数

      let mainInfos = [
        {
          title: "监控路段",
          number: allPartnersNums,
          unit: "个",
        },
        {
          title: "异常路段",
          number: unusualNums,
          unit: "个",
        },
      ]
      let datas = {
        mainInfos,
        partners
      }

      return {
        data: datas,
        code: httpCode.SUCCESS,
        message: '异常设备组查询成功！'
      }
    } catch (error) {
      this.ctx.logger.error(error);
      throw new SystemErrException("异常设备组查询异常：" + error);
    }
  }
}

module.exports = MonitorPartnersService;
